package com.rran.study.chat.gateway.config;

import com.netflix.loadbalancer.IRule;
import com.rran.study.chat.gateway.exception.GlobalExceptionHandler;
import com.rran.study.chat.gateway.limiter.MyRedisRateLimiter;
import com.rran.study.chat.gateway.rule.GrayscaleLoadBalancerRule;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.validation.Validator;
import org.springframework.web.reactive.result.view.ViewResolver;

import java.util.Collections;
import java.util.List;

/**
 * @author yy
 * @Type GatewayBootConfiguration.java
 * @Desc
 * @date 2020/8/20
 */
@Configuration
public class GatewayBootConfiguration {


    @Primary
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public ErrorWebExceptionHandler errorWebExceptionHandler(ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                                             ServerCodecConfigurer serverCodecConfigurer) {

        GlobalExceptionHandler jsonExceptionHandler = new GlobalExceptionHandler();
        jsonExceptionHandler.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList));
        jsonExceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters());
        jsonExceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders());
        return jsonExceptionHandler;
    }

    @Bean
    @Primary
    MyRedisRateLimiter myRedisRateLimiter(
            ReactiveRedisTemplate<String, String> redisTemplate,
            @Qualifier(MyRedisRateLimiter.REDIS_SCRIPT_NAME) RedisScript<List<Long>> script,
            @Qualifier("webFluxValidator") Validator validator){
        return new MyRedisRateLimiter(redisTemplate , script , validator);
    }

//    @Bean
    IRule rule(){
        return new GrayscaleLoadBalancerRule();
    }
}
